// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) definits fieldsfirst ansi space safe 
// Source File Name:   RigidBodyView.java

package jones.gui;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import jones.World;
import jones.rigid.*;

// Referenced classes of package jones.gui:
//            PositionHandle, OrientationHandle, PolygonUtils, Orientation

public class RigidBodyView extends JPanel implements Observer {

	private static final int POSITION_HANDLE_SIZE = 5;
	private static final int ORIENTATION_HANDLE_SIZE = 8;
	private static final int ORIENTATION_HANDLE_OFFSET = 3;
	private RigidBody rigidBody = null;
	private World world = null;
	private Observable observable = null;
	private ConvexPolygon shape = null;
	private PositionHandle upperLeftPositionHandle = null;
	private PositionHandle upperRightPositionHandle = null;
	private PositionHandle lowerLeftPositionHandle = null;
	private PositionHandle lowerRightPositionHandle = null;
	private OrientationHandle orientationHandle = null;
	private boolean isDragable = false;
	private boolean isPositionHandlesVisible = false;
	private boolean isOrientationHandleVisible = false;

	public RigidBodyView(RigidBody rigidBody, World world) {
		shape = new ConvexPolygon();
		isDragable = true;
		isPositionHandlesVisible = true;
		isOrientationHandleVisible = false;
		if (!(rigidBody instanceof Observable)) {
			throw new IllegalArgumentException("Rigid body must be Observable.");
		} else {
			this.rigidBody = rigidBody;
			this.world = world;
			observable = (Observable) rigidBody;
			init();
			return;
		}
	}

	private void init() {
		setOpaque(false);
		setFocusable(true);
		setEnabled(true);
		setVisible(true);
		setCursor(Cursor.getPredefinedCursor(0));
		setForeground(Color.white);
		rigidBody.getCurrentShape(shape);
		MouseInputAdapter dragListener = ((MouseInputAdapter) (new MouseInputAdapter() {

			Point2D rigidBodyStart = null;
			Point2D offset = null;

			public void mousePressed(MouseEvent e) {
				if (!isDragable) {
					return;
				} else {
					rigidBodyStart.setLocation(rigidBody.getLocationX(), rigidBody
							.getLocationY());
					offset.setLocation((double) e.getX() - rigidBodyStart.getX(),
							(double) e.getY() - rigidBodyStart.getY());
					world.removeRigidBody(rigidBody);
					return;
				}
			}

			public void mouseDragged(MouseEvent e) {
				if (!isDragable) {
					return;
				} else {
					rigidBody.setLocation((double) e.getX() - offset.getX(), (double) e
							.getY()
							- offset.getY());
					observable.notifyObservers();
					return;
				}
			}

			public void mouseReleased(MouseEvent e) {
				if (!isDragable)
					return;
				try {
					world.addRigidBody(rigidBody);
				} catch (OverlappingRigidBodyException ex) {
					JOptionPane.showMessageDialog(
							((java.awt.Component) (RigidBodyView.this)),
							"Rigid bodies cannot overlap.", "OverlappingRigidBodyException",
							0);
					rigidBody.setLocation(rigidBodyStart.getX(), rigidBodyStart.getY());
					world.addRigidBody(rigidBody);
					observable.notifyObservers();
				}
			}

			{
				rigidBodyStart = ((Point2D) (new java.awt.geom.Point2D.Double()));
				offset = ((Point2D) (new java.awt.geom.Point2D.Double()));
			}
		}));
		addMouseListener(((java.awt.event.MouseListener) (dragListener)));
		addMouseMotionListener(((java.awt.event.MouseMotionListener) (dragListener)));
		addMouseListener(((java.awt.event.MouseListener) (new MouseAdapter() {

			public void mousePressed(MouseEvent e) {
				requestFocusInWindow();
				repaint();
			}

		})));
		Orientation orientation = ((Orientation) (new Orientation() {

			public void setLocation(double x, double y) {
				rigidBody.setLocation(x, y);
				observable.notifyObservers();
			}

			public double getX() {
				return rigidBody.getLocationX();
			}

			public double getY() {
				return rigidBody.getLocationY();
			}

			public void setAngle(double angle) {
				rigidBody.setOrientation(angle);
				observable.notifyObservers();
			}

			public double getAngle() {
				return rigidBody.getOrientation();
			}

			public void update(Observable obs, Object obj) {
				setChanged();
				notifyObservers();
			}

		}));
		observable.addObserver(((Observer) (orientation)));
		double minX = shape.getMinX();
		double maxX = shape.getMaxX();
		double minY = shape.getMinY();
		double maxY = shape.getMaxY();
		Rectangle handleShape = new Rectangle(5, 5);
		handleShape.setLocation((int) (minX - 5D), (int) (minY - 5D));
		upperLeftPositionHandle = new PositionHandle(((Position) (orientation)),
				((java.awt.geom.RectangularShape) (handleShape)));
		handleShape.setLocation((int) maxX, (int) (minY - 5D));
		upperRightPositionHandle = new PositionHandle(((Position) (orientation)),
				((java.awt.geom.RectangularShape) (handleShape)));
		handleShape.setLocation((int) (minX - 5D), (int) maxY);
		lowerLeftPositionHandle = new PositionHandle(((Position) (orientation)),
				((java.awt.geom.RectangularShape) (handleShape)));
		handleShape.setLocation((int) maxX, (int) maxY);
		lowerRightPositionHandle = new PositionHandle(((Position) (orientation)),
				((java.awt.geom.RectangularShape) (handleShape)));
		Ellipse2D ellipse = ((Ellipse2D) (new java.awt.geom.Ellipse2D.Double(
				maxX + 3D, ((maxY + minY) - 8D) / 2D, 8D, 8D)));
		orientationHandle = new OrientationHandle(orientation,
				((java.awt.geom.RectangularShape) (ellipse)));
		orientationHandle.setVisible(false);
		setLayout(((java.awt.LayoutManager) (new OverlayLayout(
				((java.awt.Container) (this))))));
		add(((java.awt.Component) (upperLeftPositionHandle)));
		add(((java.awt.Component) (upperRightPositionHandle)));
		add(((java.awt.Component) (lowerLeftPositionHandle)));
		add(((java.awt.Component) (lowerRightPositionHandle)));
		add(((java.awt.Component) (orientationHandle)));
		addFocusListener(new FocusListener() {

			public void focusGained(FocusEvent e) {
				if (isPositionHandlesVisible) {
					upperLeftPositionHandle.setVisible(true);
					upperRightPositionHandle.setVisible(true);
					lowerLeftPositionHandle.setVisible(true);
					lowerRightPositionHandle.setVisible(true);
				}
				if (isOrientationHandleVisible)
					orientationHandle.setVisible(true);
				repaint();
			}

			public void focusLost(FocusEvent e) {
				upperLeftPositionHandle.setVisible(false);
				upperRightPositionHandle.setVisible(false);
				lowerLeftPositionHandle.setVisible(false);
				lowerRightPositionHandle.setVisible(false);
				orientationHandle.setVisible(false);
				repaint();
			}

		});
		requestFocusInWindow();
	}

	public void update(Observable obs, Object obj) {
		rigidBody = (RigidBody) obs;
		synchronized (shape) {
			rigidBody.getCurrentShape(shape);
		}
		repaint();
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(getForeground());
		synchronized (shape) {
			PolygonUtils.drawPolygon(((jones.rigid.Polygon) (shape)),
					((Graphics) (g2d)));
		}
	}

	public boolean contains(int x, int y) {
		ConvexPolygon convexpolygon = shape;
		return shape.contains(x, y)
				|| hasFocus()
				&& isPositionHandlesVisible
				&& (upperLeftPositionHandle.contains(x, y)
						|| upperRightPositionHandle.contains(x, y)
						|| lowerLeftPositionHandle.contains(x, y) || lowerRightPositionHandle
						.contains(x, y)) || isOrientationHandleVisible
				&& orientationHandle.contains(x, y);
	}

	public void setDragable(boolean isDragable) {
		this.isDragable = isDragable;
	}

	public void setPositionHandlesVisible(boolean isPositionHandlesVisible) {
		this.isPositionHandlesVisible = isPositionHandlesVisible;
		repaint();
	}

	public void setOrientationHandleVisible(boolean isOrientationHandleVisible) {
		this.isOrientationHandleVisible = isOrientationHandleVisible;
		repaint();
	}

}
